const {CachesBuilder} = require('./Cache')
const {env} =require('process')
const repl = require('repl')
const {table} = require('table')
const Protocol = require('./Protocol')
const {Snooper, Directory} = require('./Strategy')
const colors = require('colors')

env.lang = 'zh'
let prompts = ['监听> ','目录> '] 
let strategies = [Snooper,Directory] 
let sys = CachesBuilder(4,4)
const replServer = repl.start({prompt:prompts[0],useColors:true})

/**
 * 改变协议并重置系统
 */
replServer.defineCommand('ch',{
    help:'切换为另一种协议并重启',
    action(){
        this.clearBufferedCommand()
        prompts.push(prompts.shift())
        strategies.push(strategies.shift())
        Protocol.use(new strategies[0](sys.length,sys[0].size))
        this.setPrompt(prompts[0])
        sys = CachesBuilder(sys.length,sys[0].size)
        this.displayPrompt()
    }
})

replServer.defineCommand('write',{
    help:'处理器写 例如:write 1 2 表示 1 号处理器往2号内存写',
    action(command){
        this.clearBufferedCommand()
        try{
            let [processor,ram] = command.split(/\s+/).map(x=>parseInt(x))
            sys[processor].write(ram)
        }catch(e){
            console.error('请输入正确命令格式')
        }
        this.displayPrompt()
    }
})

replServer.defineCommand('read',{
    help:'处理器读 例如:read 1 2 表示 1 号处理器往2号内存读',
    action(command){
        this.clearBufferedCommand()
        try{
            let [processor,ram] = command.split(/\s+/).map(x=>parseInt(x))
            sys[processor].read(ram)
        }catch(e){
            console.error('请输入正确命令格式')
        }
        this.displayPrompt()
    }
})

replServer.defineCommand('en',{
    help:'转换为英文',
    action(){
        this.clearBufferedCommand()
        env.lang = 'en'
        console.log('language has change to English')
        this.displayPrompt()
    }
})

replServer.defineCommand('zh',{
    help:'change language to English',
    action(){
        this.clearBufferedCommand()
        env.lang = 'zh'
        console.log('语言变成中文')
        this.displayPrompt()
    }
})

replServer.defineCommand('reset',{
    help:'重置,例如reset 4 8 表示重置出的机器拥有4个处理机，每个处理机8个cache块',
    action(command){
        this.clearBufferedCommand()
        if(command){
            try{
                let [processor,ram] = command.split(/\s+/).map(x=>parseInt(x))
                sys = CachesBuilder(processor,ram)
            }catch(e){
                console.error('请输入正确命令格式')
            }
        }else{
            sys = CachesBuilder(4,4)
        }
        Protocol.use(new strategies[0](sys.length,sys[0].size))
        this.displayPrompt()
    }
})

replServer.defineCommand('show',{
    help:'展示cache状态',
    action(){
        this.clearBufferedCommand()
        let info = []
        for(let j = 0;j < sys[0].size;j++){
            info[j] = [j]
            for(let i = 0;i < sys.length;i++){
                info[j].push(sys[i].cacheBlocks[j].currentState.getName())
            }
        }
        info.unshift([`缓存\\处理机`].concat(Array(sys.length).fill(0).map((v,i) => i)))
        //如果是目录协议，打印目录
        if(strategies[0] === Directory){
            let dir = Array(sys[0].size * 2).fill(0).map((v,i) => [i])
            for(let i = 0; i < Protocol.strategy.ram.length;i++){
                let content = [...Protocol.strategy.ram[i]].map(x => x.processor).toString()
                dir[i % (sys[0].size * 2)].push(colors.gray(`(${i})`) + content || '')
            }
            dir.unshift([`目录 内存总量${Protocol.strategy.ram.length}`].concat(Array(sys.length).fill(0).map((v,i) => i)))
            info = info.concat(dir)
        }
        // console.log(info)
        console.log(table(info))
        this.displayPrompt()
    }
})

